Re: Using GSettings to set for all users

2010-06-03 Thread David Zeuthen
Hi,

(It would probably be good to open a bug about this instead of doing
it on a mailing list...)

Here's a couple of comments. First, there's an assumption hard-wired
into all of this that polkit works like this

 - Obtain an authorization to do XYZ
 
 - actually do XYZ

while that's actually not true. The way polkit works is described here

 http://hal.freedesktop.org/docs/polkit/polkit.8.html

Also, your mail about how this will work with polkit is a bit
hand-wavy at this point - I think it would help to prototype it before
proposing or discussing API additions.

Indulge some rambling about polkit: Given an action id XYZ, a
Mechanism typically want to inquire whether a Caller (or Client) is
authorized - there are three possibilities

 - The Caller is already authorized for XYZ.

 - The Caller is not authorized for XYZ and an authorization cannot
   be obtained

 - The Caller is not authorized for XYZ and an authorization can be
   obtained by authenticating the user.
   - the obtained authorization is either one-shot or it is temporary

At this point, already, we need to identify what the Caller and what
the Mechanism is.

Clearly, the Caller is the GSettings-using app, e.g. typically an
unprivileged GTK+ preference dialog or whatever.

The Mechanism here is dconf which obviously is privileged since it can
write to the defaults area (doesn't that it is uid 0, just means that
it has additional (or different if you want) privileges than the
Caller. E.g. if not uid 0, it runs with a fixed uid, e.g. a uid for
the username "dconf" or something.).

Also,

 - You need to think about the polkit action id's and mention how this
   can be overridden the same way it works in gconf, e.g. similar to
   org.gnome.gconf.defaults.policy and

   $ grep -1 annotate
/usr/share/polkit-1/actions/org.gnome.control-center.defaultbackground.policy

/desktop/gnome/background
  

   e.g. for keys prefixed with /desktop/gnome/background, the
   org.gnome.control-center.defaultbackground polkit action id
   is used.

   Or more succinct: please do look at how the work Matthias
   already did for gconf and consider just copying that!

 - Calls into polkit that causes an authentication dialog to be shown
   (e.g. code that passes the ALLOW_USER_INTERACTION flag)
   needs to come from a Privileged Component so the you can set the
   GSettings key-name in the @details argument of CheckAuthorization().
   This allows apps to ship a PolkitBackendActionLookup extension so
   they can override the contents of the authentication dialog.

   http://hal.freedesktop.org/docs/polkit/PolkitBackendActionLookup.html

   Note that you can still have unprivileged code _check_ the
   authorization without setting the @details argument as long as you
   don't pass the ALLOW_USER_INTERACTION_FLAG. This is what
   you want to use in the client-side implementation of, say,
   g_settings_canhasprivs().

   (Btw, g_settings_canhasprivs() with polkit *will* involve a D-Bus
   call to the polkit Authority so you need the _sync, _async and
   _finish() variants... unless you rethink the API. I don't know)

   (Also: right now "Privileged Component" means uid 0. But as I
   said yesterday on IRC, I'm going to make it possible to make e.g.
   dconf drop a file somewhere so unix-user "dconf" (or "nobody",
   or "whatever"...) is also allowed to pass non-empty @details).

Hope this helps.

 David
___
desktop-devel-list mailing list
desktop-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/desktop-devel-list


Re: Using GSettings to set for all users

2010-06-03 Thread Bastien Nocera
On Thu, 2010-06-03 at 17:40 +0200, Ryan Lortie wrote:
> On Thu, 2010-06-03 at 10:30 -0400, Matthias Clasen wrote:
> > On Thu, Jun 3, 2010 at 5:15 AM, Richard Hughes  wrote:
> > >  The only remaining bits to port is the "set default"
> > > button which sets the per-user settings for all users.    I'm
> > > unsure on how to port this in a GSettings/dconf world.
> >
> > This was being discussed between Ryan and David just yesterday. I'm
> > sure Ryan can shed some light on the current plans.
> 
> So first of all, a little bit of knowledge about how dconf and GSettings
> handle access to the system defaults database:
> 
> Both systems support the concept of "context" to allow you to access
> something other than the user's normal database of settings.  You can
> give a context of "default" to access the system default settings, for
> example.
> 
> My current thinking for the write-to-defaults API is along these lines:
> 
> GSettings exposes via is_writable() if a key is writable at this moment.
> In the case that the key may become writable in the future, given proper
> policy kit authentication then this function still returns FALSE.  This
> allows preferences dialogs with "unlock" buttons to work properly and
> show the controls as insensitive while the dialog is "locked".


With that API, wouldn't there be a case where the user could change the
value of a setting in between "make default" being called, and the
application actually writing those settings as defaults?

Or is that not something we worry about?

___
desktop-devel-list mailing list
desktop-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/desktop-devel-list


Re: Using GSettings to set for all users

2010-06-03 Thread Ryan Lortie
On Thu, 2010-06-03 at 10:30 -0400, Matthias Clasen wrote:
> On Thu, Jun 3, 2010 at 5:15 AM, Richard Hughes  wrote:
> >  The only remaining bits to port is the "set default"
> > button which sets the per-user settings for all users.    I'm
> > unsure on how to port this in a GSettings/dconf world.
>
> This was being discussed between Ryan and David just yesterday. I'm
> sure Ryan can shed some light on the current plans.

So first of all, a little bit of knowledge about how dconf and GSettings
handle access to the system defaults database:

Both systems support the concept of "context" to allow you to access
something other than the user's normal database of settings.  You can
give a context of "default" to access the system default settings, for
example.

My current thinking for the write-to-defaults API is along these lines:

GSettings exposes via is_writable() if a key is writable at this moment.
In the case that the key may become writable in the future, given proper
policy kit authentication then this function still returns FALSE.  This
allows preferences dialogs with "unlock" buttons to work properly and
show the controls as insensitive while the dialog is "locked".

Probably I will add a new API:

gboolean g_settings_canhasprivs(GSettings *);

This will return TRUE if it's possible that the user might gain
additional privileges from authenticating against PolicyKit.

also:

void g_settings_gimmeprivs(GSettings *);

Will actually go and try to get those privs.  This function is
non-blocking -- all it does is send a request to PolicyKit to give the
privs and return immediately.  If and when the privs are successfully
granted this will be reflected by the is_writable() property returning
TRUE (and the application will be notified by the writability-changed
signal).  The same thing would happen if the privileges were requested
by another application but affected this one.  I like this approach.

So that's the story for the "unlock this dialog" case, but I understand
that there is another case for "copy some setting to the defaults".

Given the API that I plan to add for the previously mentioned case, you
could almost do this for yourself:

  GSettings *prefs = g_settings_new ("my.prefs");

... you are doing stuff with prefs, then the user clicks 

  GSettings *def = g_settings_new_with_context ("my.prefs", "default");
  if (!g_settings_is_writable (def, "key") &&
  g_settings_canhasprivs(def))
g_settings_gimmeprivs();
  g_settings_set_value (def, "key",
g_settings_get_value (prefs, "key"));

this could work, but the problem is that gimmeprivs() won't block until
you have the privs, so the set_value() call that you try to do too
quickly will fail.

What is needed is three new calls implementing a variant of
gimmeprivs().  These three calls are of course the traditional _sync(),
_async() and _finish() calls.  In this case, the application will be
able to detect when the authentication has succeeded (or failed) and go
ahead with the write (or bail out) accordingly.

Probably I will add these.

Finally, it might be useful to have a helper to do all of this:

gboolean g_settings_push (GSettings*settings,
  const gchar  *key,
  const gchar  *context,
  GError  **error);

that does all of the above internally.

you would use it like this:

  g_settings_push (prefs, "my-key", "default", NULL);

which would block your app, pop up a PolKit dialog and do its thing,
returning TRUE on success.

of course, there would be a _sync/_finish version too.

So, 8 new functions:
  - canhasprivs
  - gimmeprivs
  - gimmeprivs_sync
  - gimmeprivs_async
  - gimmeprivs_finish
  - push
  - push_async
  - push_finish

It's possible that i don't expose the _sync/_async/_finish versions of
gimmeprivs because with _push() there is no real use case for having
these.

That's it.  Bye :)

___
desktop-devel-list mailing list
desktop-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/desktop-devel-list


Re: Using GSettings to set for all users

2010-06-03 Thread Matthias Clasen
On Thu, Jun 3, 2010 at 5:15 AM, Richard Hughes  wrote:
> I'm about ready to push my gsettings branch of gnome-power-manager
> into master. The only remaining bits to port is the "set default"
> button which sets the per-user settings for all users. This used to
> work using the DBus interface of GConf (the policykit helper), but I'm
> unsure on how to port this in a GSettings/dconf world. Ideas welcome.
>

This was being discussed between Ryan and David just yesterday. I'm
sure Ryan can shed some light on the current plans.


Matthias
___
desktop-devel-list mailing list
desktop-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/desktop-devel-list


Using GSettings to set for all users

2010-06-03 Thread Richard Hughes
I'm about ready to push my gsettings branch of gnome-power-manager
into master. The only remaining bits to port is the "set default"
button which sets the per-user settings for all users. This used to
work using the DBus interface of GConf (the policykit helper), but I'm
unsure on how to port this in a GSettings/dconf world. Ideas welcome.

Thanks,

Richard.
___
desktop-devel-list mailing list
desktop-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/desktop-devel-list