Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security fix & lock for HomeMatic #11980

Merged
merged 16 commits into from Mar 25, 2018
Merged

Conversation

PH89
Copy link
Contributor

@PH89 PH89 commented Jan 28, 2018

Description:

This PR intruduces a new lock component for HomeMatic door locks.
It also improves the general base lock component by adding a 3rd service open, that makes it possable to open the door by releasing the door latch.

Pull request in documentation:
home-assistant/home-assistant.io#4537

Pull request in Frontend:
https://github.com/home-assistant/home-assistant-polymer#845

Checklist:

  • The code change is tested and works locally.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

Locks may are capable to open the door latch.
If component is support it, the SUPPORT_OPENING bitmask can be supplied in the supported_features property.
def supported_features(self):
"""Flag supported features."""
return SUPPORT_OPENING

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line at end of file

@PH89
Copy link
Contributor Author

PH89 commented Jan 28, 2018

Checks okay from my side. Travis job timed out.

@PH89
Copy link
Contributor Author

PH89 commented Jan 28, 2018

@danielperna84 What does this breaking change label mean?
This code should not break anything with other lock components.

@danielperna84
Copy link
Contributor

It will break automations. Until now the component has been a switch. Having it as a lock-platform requires the automations to be changed accordingly. So when the switch.turn_on service was used before to change the state, this will not work anymore. Except when I'm missing something here. I don't own such locks, so I don't know how they are practically used. But my assumption would be, that they are currently used with the switch-services.

@property
def is_locked(self):
"""Return true if the lock is locked."""
return self._hmdevice.is_locked()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can only access to self._data inside a property

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pvizeli Oh okay... Can you give a short explanation why this is the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pvizeli I think this is resolved now by returning not self._hm_get_state() here.

However it is possable to access self._hmdevice, after the homematic device is linked.
Durring my testing the is_locked method is only called after the device is linked and the self._hmdevice is set up.
Please correct me if I am wrong and explain it in a little more detail.

@pvizeli
Copy link
Member

pvizeli commented Jan 30, 2018

@andrey-git @MartinHjelmare I have no door device. If that change legitime for all lock systems or should that be a platform only service?

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the new open service is valid as a general lock service. I think opening the door is a thing among smart locks.

There should also be a module level function to call the new service in the lock component.

@@ -39,6 +39,9 @@
vol.Optional(ATTR_CODE): cv.string,
})

# Bitfield of features supported by the lock entity
SUPPORT_OPENING = 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be called SUPPORT_OPEN.

@andrey-git
Copy link
Contributor

@pvizeli I think that as long there is a single device (homematic) that supports "open" the service would be better at the platform level. However "supported_features" must be on the component level (for UI support) so I'm OK with the service being on component level.

try:
return not self._hm_get_state()
except TypeError:
return False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simple: return not bool(self._hm_get_state())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pvizeli Okay I simplified the statement.

def supported_features(self):
if self._openable:
return SUPPORT_OPEN

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line at end of file

lock.open(self.hass, OPENABLE_LOCK)
self.hass.block_till_done()

self.assertFalse(lock.is_locked(self.hass, OPENABLE_LOCK))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no newline at end of file

@PH89
Copy link
Contributor Author

PH89 commented Mar 1, 2018

@pvizeli Requested changes are made from my site. Can you review it?

@pvizeli
Copy link
Member

pvizeli commented Mar 4, 2018

Please fix the lint


def open(self, **kwargs):
"""Open the door latch."""
self._state = STATE_OPEN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lock component only know STATE_UNLOCKED, STATE_LOCKED

lock.open(self.hass, OPENABLE_LOCK)
self.hass.block_till_done()

self.assertFalse(lock.is_locked(self.hass, OPENABLE_LOCK))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mock also the service call and look if they will be called

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example for me how to do this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danielperna84
Copy link
Contributor

Any chance this can be included in the next version? The changes in pyhomematic that were needed to allow the Lock component caused a break for the existing implementation that is using the switch. This has been mentioned here: https://community.home-assistant.io/t/homematic-hm-sec-key-not-working-after-upgrading-to-0-64-0-65/46693
Failing automations that should lock doors are a BIG security issue. I wasn't aware of that since I myself don't own such devices.

In my opinion there are two solutions to this:

  1. This PR gets merged (possibly without the requested test).
  2. I revert the changes in pyhomematic to restore the previous functionality.

I personally would favour the 1. approach since completing the tests seems to be much less effort than reverting quite some code in pyhomematic.

@PH89
Copy link
Contributor Author

PH89 commented Mar 23, 2018

I will focus on completing the tests this weekend.

@PH89
Copy link
Contributor Author

PH89 commented Mar 25, 2018

@pvizeli Tests now with service mocks.

@pvizeli pvizeli added this to the 0.66 milestone Mar 25, 2018
@pvizeli
Copy link
Member

pvizeli commented Mar 25, 2018

I tag this for 0.66 while it is a security hole for all they use this device

@pvizeli pvizeli changed the title Lock component for HomeMatic KeyMatic Security fix & lock for HomeMatic Mar 25, 2018
@pvizeli pvizeli merged commit 6d20a84 into home-assistant:dev Mar 25, 2018
balloob pushed a commit that referenced this pull request Mar 26, 2018
* HomeMatic KeyMatic device become a real lock component

* Adds supported features to lock component.

Locks may are capable to open the door latch.
If component is support it, the SUPPORT_OPENING bitmask can be supplied in the supported_features property.

* hound improvements.

* Travis improvements.

* Improvements from review process

* Simplifies is_locked method

* Adds an openable lock in the lock demo component

* removes blank line

* Adds test for openable demo lock and lint and reviewer improvements.

* adds new line...

* Comment end with a period.

* Additional blank line.

* Mock service based testing, lint fixes

* Update description
@balloob balloob mentioned this pull request Mar 30, 2018
@home-assistant home-assistant locked and limited conversation to collaborators Jul 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants