Merge lp://staging/~tealeg/landscape-client/ui-permissions-and-panel into lp://staging/~landscape/landscape-client/trunk

Proposed by Geoff Teale
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 452
Merge reported by: Geoff Teale
Merged at revision: not available
Proposed branch: lp://staging/~tealeg/landscape-client/ui-permissions-and-panel
Merge into: lp://staging/~landscape/landscape-client/trunk
Diff against target: 1973 lines (+1357/-278)
29 files modified
applications/landscape-client-settings.desktop (+17/-0)
dbus-1/com.canonical.LandscapeClientRegistration.conf (+16/-0)
dbus-1/com.canonical.LandscapeClientRegistration.service (+4/-0)
dbus-1/com.canonical.LandscapeClientSettings.conf (+16/-0)
dbus-1/com.canonical.LandscapeClientSettings.service (+4/-0)
icons/preferences-management-service.svg (+78/-0)
landscape/ui/controller/app.py (+2/-2)
landscape/ui/controller/configuration.py (+24/-15)
landscape/ui/controller/tests/test_app.py (+17/-19)
landscape/ui/controller/tests/test_configuration.py (+54/-39)
landscape/ui/lib/polkit.py (+115/-0)
landscape/ui/model/configuration/mechanism.py (+98/-0)
landscape/ui/model/configuration/proxy.py (+77/-0)
landscape/ui/model/configuration/tests/test_mechanism.py (+174/-0)
landscape/ui/model/configuration/tests/test_proxy.py (+127/-0)
landscape/ui/model/registration/mechanism.py (+114/-82)
landscape/ui/model/registration/proxy.py (+87/-0)
landscape/ui/model/registration/tests/test_mechanism.py (+45/-0)
landscape/ui/model/registration/tests/test_proxy.py (+56/-0)
landscape/ui/model/tests/test_registration.py (+0/-80)
landscape/ui/tests/helpers.py (+39/-0)
landscape/ui/view/configuration.py (+5/-4)
landscape/ui/view/tests/test_configuration.py (+28/-28)
polkit-1/com.canonical.LandscapeClientRegistration.policy (+21/-0)
polkit-1/com.canonical.LandscapeClientSettings.policy (+21/-0)
scripts/landscape-client-registration-mechanism (+15/-0)
scripts/landscape-client-settings-mechanism (+17/-0)
setup.py (+3/-9)
setupui.py (+83/-0)
To merge this branch: bzr merge lp://staging/~tealeg/landscape-client/ui-permissions-and-panel
Reviewer Review Type Date Requested Status
Free Ekanayaka (community) Approve
Thomas Herve (community) Approve
Review via email: mp+89248@code.staging.launchpad.net

Description of the change

Fixes bug #911665

The following changes have been made:
  - Split Configuration model into a DBus service mechanism and a proxy for the client.
  - Split Registration model in to a DBus service mechanism and a proxy for the client (with asynchronous registration).
  - Create PolicyKit policies for configuration and registration and cause these to be checked by the relevant DBus service mechanism when it receives dbus calls (effectively trigger a challenge for a password and only allow admin users to continue).
   - Create DBus service and conf files for the two service mechanisms (Allowing them to be run by the System bus on demand)
   - Create an application desktop file causing the landscape-client-settings-ui program to be launchable from gnome-control-center
   - Create the icon preferences-management-service.svg to represent this activity in gnome-control-center.
   - Create setupui.py - a distutils script for the settings-ui components.

To test all this you will need to run:
    sudo setup.py install
    sudo setupui.py install

... and then open gnome-control-center (either from the command line or from the "System Settings" item on the cog menu in Unity).

To post a comment you must log in.
Revision history for this message
Thomas Herve (therve) wrote :

[1] Please add docstrings to PolicyKitMechanism and its methods.

[2] Instead of exposing 10 methods in ConfigurationMechanism, 2 for each config value, would it be possible to have only 2 methods taking the config key as parameters? This would simplify ConfigurationProxy as well.

[3] All your tests need docstrings.

[4] Is it expected that register_fail/register_error don't do anything?

[5] I've changed trunk so that tests are skipped properly if the Gtk/Gdk imports fail, please preserve the behavior.

Thanks!

review: Needs Fixing
442. By Geoff Teale

Merge trunk into branch

443. By Geoff Teale

Add docstings (from review requests from therve)

444. By Geoff Teale

Merged trunk onto branch (ensure therve's test changes are maintained)

445. By Geoff Teale

Comment DBus notifications to explain why they are methods containing only 'pass'

446. By Geoff Teale

Reduce configuration mechanism to just a single get method and a single set method as suggested by therve in review

447. By Geoff Teale

Lint

448. By Geoff Teale

Add docstrings to test cases

Revision history for this message
Geoff Teale (tealeg) wrote :

Hi Thomas.

I've addressed your points in the code and merged in the testing changes from trunk. Could you re-review please.

Specifically with regard to point 4: yes and no, or rather it is expected that those methods are essentially empty they are called for the side-effect implied by their decorators - it's quite common to just print the parameters instead of passing, but this looks messy to me. I have added comments to all four notification methods to explain why they just pass. Gotta love that DBus ;-)

Revision history for this message
Thomas Herve (therve) wrote :

[6]
+ def setUp(self, config):
+ super(ConfigurationProxyBaseTest, self).setUp()
+ self.config_filename = self.makeFile(config)

It'd be good to reserve setUp for the real unittest setUp. Maybe "def configure_proxy" or something would be more explicit.

[7] Note that you don't need to add "pass" when a method has a docstring.

[8]
+ readables, w, x = select.select(
+ [self.process.stdout, self.process.stderr], [], [], 0)

There are so many ways this can go wrong... Let's switch to a blocking call for now, and we'll see if 1) we can improve landscape-config to handle progress better and then 2) send it there to the UI.

[9]
+ def _get_account_name(self):
+ return self._interface.get("account_name")
+
+ def _set_account_name(self, value):
+ self._interface.set("account_name", value)
+ account_name = property(_get_account_name, _set_account_name)

You should be able to reduce duplication with some functions:

def _delegate_to_interface(field):
    def get(self):
        return self._interface.get(field)
    def set(self, value):
        self._interface.set(field, value)

account_name = property(*_delegate_to_interface("account_name")
computer_title = property(*_delegate_to_interface("computer_title")

Thanks, +1!

review: Approve
Revision history for this message
Geoff Teale (tealeg) wrote :

All the above requests from Thomas have been implemented.

449. By Geoff Teale

Make subprocess registration in the mechanism synchronous at therve's suggestion

450. By Geoff Teale

Removed unneeded passes

451. By Geoff Teale

Reduced duplications by generating get/set property pairs (suggestion from therve)

452. By Geoff Teale

lint

Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :
Download full text (3.5 KiB)

Hi Geoff, nice work, I have a few comments but mostly stylistic ones. The changeset is rather large and takes a while to read, please break it down in smaller branches next time (the diff should be ~500 lines).

+1!

[1]

+it's calls via DBus to the L{ConfigurationMechanism}.

s/it's/its/

[2]

+class RegistrationProxy(object):

It'd be good to add a class docstring for this class.

[3]

+class ConfigurationProxyBaseTest(LandscapeTest):

It'd be good to use composition instead of inheritance. The LandscapeTest class has support for "helpers" (sort of plugins/fixtures), you can find some examples in landscape.tests.helpers (see HelperTestCase) and landscape.broker.tests.helpers. We could have landscape.ui.tests.helpers.ConfigurationProxyHelper.

[4]

+ class MyLandscapeSetupConfiguration(LandscapeSetupConfiguration):
+ default_config_filenames = [self.config_filename]
+
+ self.config = MyLandscapeSetupConfiguration()

I *think* you don't need a full subclass for this, just:

        self.config = LandscapeSetupConfiguration()
        self.config.default_config_filenames = [self.config_filename]

[5]

+ # from dbus.service.Object which throws a fit it notices you using it

s/it notices/if it notices/ ?

[6]

+ ConfigurationProxy._setup_interface = setup_interface
+ self.proxy = ConfigurationProxy()

This seems to modify the actual class (without cleaning it in tearDown). Also, you could achieve the same without patching the original class by adding the interface object as parameter:

    def __init__(self, interface=None):
        self._interface = interface
        if self._interface is None:
            self._bus = dbus.SystemBus()
            self._remote_object = self._bus.get_object(SERVICE_NAME, OBJECT_PATH)
            self._interface = dbus.Interface(self._remote_object, INTERFACE_NAME)

[7]

+ implemented via PolicyKit policy. The use of DBus results from the use of
+ PolicyKit, not the other way around, and is done that way because that is
+ considered to be the Right Thing for Ubuntu Desktop circa January 2012.

Nice design defense :)

[8]

+ def __init__(self, config, bus_name, bypass=False, conn=None):
+ super(ConfigurationMechanism, self).__init__(
+ OBJECT_PATH, bus_name, PermissionDeniedByPolicy,
+ bypass=bypass, conn=conn)
+ self.config = config

I presume self.config could be private (self._config).

[9]

+ Test that we can get and set and account name via the configuration

s/and account/an account/

[10]

+ self.assertEqual(self.proxy.account_name, "foo")
+ self.proxy.account_name = "bar"
+ self.assertEqual(self.proxy.account_name, "bar")

It's probably not strictly needed, but it'd be nice to also assert that the "remote" config object gets actually modified:

self.assertEqual(self.config.account_name, "bar")

[11]

All the assertions should be inverted, the pattern we adopt is the one recommended by unittest and (xUnit in general afaict):

self.assertEqual(expected_value, actual_value)

It's been counter-intuitive for me at start, but I eventually adjusted.

[12]

+ def setUp(self, config):
+ ...

Read more...

review: Approve
453. By Geoff Teale

Remove a Grocer's apostrophe / Deppenapostroph from docstring

454. By Geoff Teale

Added docstring to RegistrationProxy class

455. By Geoff Teale

Convert ConfigurationProxyBaseTest into a helper (Inheritence -> Composition) as suggested by Free

456. By Geoff Teale

lint

457. By Geoff Teale

Pushed interface into an optional parameter in ConfigurationProxy.__init__ instead of using _setup_interface. As suggested by Free

458. By Geoff Teale

self.config -> self._config (suggested by Free's review)

459. By Geoff Teale

Fix typo in docstring

460. By Geoff Teale

Add assertions to test whether config changes are really passed through to the underlying configuration object when set via the ConfigurationProxy. From Free's review suggestions.

461. By Geoff Teale

Flipped assertEquals invocations to comply with xUnit style (expected first). From Free's review

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches

to all changes: