qhue icon indicating copy to clipboard operation
qhue copied to clipboard

Supporting Hue API v2

Open ticalc-travis opened this issue 2 years ago • 6 comments

Here is a WIP attempt to add support for the upcoming version 2 of the Philips Hue API to qhue. Feedback and collaboration welcome. :-) Version 2 of the API is currently in early access, not yet feature complete, but Philips intends to someday have it replace the existing version 1.

In this draft, access to the new API is implemented via the provisionally-named Bridge_APIv2 and Resource_APIv2 classes. Due to differences in how the v2 API reports errors, these also use a separate exception class, QhueException_APIv2, which implements a different set of properties. The original Bridge and QhueException objects are still available for API v1 access, since some functionality is only available in v1 at the moment; their semantics should be unchanged. For now, it seems that v2 uses the same usernames (now called application keys), so the existing create_new_username function should work for both versions of the API (though at the moment it still uses the unencrypted HTTP connection).

Key differences of the new API include:

  • HTTPS is mandatory; no more HTTP support
  • A different root URL (/clip/v2 instead of /api/<username>)
  • Application usernames/keys are passed as an HTTP header rather than being part of the URL
  • Completely reworked resource paths and semantics
  • HTTP response codes are used to report all errors, and response bodies include the top-level JSON items “errors” which lists any errors and “data” for all other information.

At this point, basic GETs and PUTs to the new API appear to work, though more thorough testing needs to be done.

Other work left to do:

HTTPS certificate validation: I'm not too knowledgeable with TLS matters, so this is the most difficult problem for me. The requests module will complain about the bridge's HTTPS certificate because it will not recognize the root CA. Furthermore, it expects the domain name to match that specified in the certificate (which will be the bridge's ID), and this will almost certainly not be the case on a typical user's home network. Further complicating matters is that some bridges still use the older self-signed certificates rather than the newer ones Philips says they'll eventually be rolling out, so this will also need to be handled.

Philips suggests implementing a custom domain name verifier that checks the bridge ID (which still needs to be initially obtained somehow) against that in the certificate. I do not yet know how this can be done with requests. For testing purposes, I've for now disabled certificate validation (and squelched the resulting warning message), but this is something we probably want to do properly at some point. If anyone knows how to make this work without severely hurting usability, I'm all ears. :-)

Event stream support: API v2 has a new event stream that apps can subscribe to to be notified about changes on the bridge. This would probably be best implemented using a different sort of class, or perhaps as a callback. I haven't looked into this yet.

Remote API support: I have never used this personally, so I don't know yet how this works with respect to v2.

Examples and documentation, etc., for the newer API

ticalc-travis avatar May 08 '22 20:05 ticalc-travis

Travis - very many thanks for your work on this!

It may be a short while before I can look at it in any detail, but I just wanted to let you know I was appreciative of your efforts!

Quentin

quentinsf avatar May 08 '22 22:05 quentinsf

Thanks! No hurry. :-)

I've researched the HTTPS support in particular a bit more and came up with some ideas, but I'm not really that happy with them. This situation is pretty ugly all around.

In principle, I worked out how to include the root CA for the Hue bridge in the qhue package and coerce requests/urllib3 into accepting it and also accepting it based on a known bridge ID (which would be supplied by the user of the library in addition to the IP/host and app key) irrespective of the host/IP used to connect to it. But Python's libs insist on having certs passed by physical file paths, not in-memory buffers, so that would mean copying it to a temporary location just so it can be passed. The package interface Python offers for storing data files in the package makes you use it as a context manager so it can clean up temp files if it needs to make them, but this doesn't fit this use case, where the temp file needs to exist as long as all Bridge/Resource objects remain alive (or else potentially recreate and destroy it on every single HTTPS request, which is needless overhead).

On top of that, I get warnings about the Philips bridge cert using an obsolete feature that will no longer be supported in urllib3 2.0. (Details at https://github.com/urllib3/urllib3/issues/497) So unless they fix that, then it sounds like this workaround would eventually break anyway.

Finally, what if someone wants to use a competing third-party Hue-bridge-like device with qhue instead of the official one? I think they ought to be able to do that, and since such a product couldn't use the same certs, hardcoding recognition of only the Philips one would be a significant obstacle unless we implemented an interface for adding an alternate one. Ugh.

Maybe I missed something, but it really makes me question if HTTPS verification for the bridge itself is worth bothering with at all. It makes sense on untrusted networks like the internet, where you want to be sure you're really communicating with the service you think you are. But the Hue bridge is intended to be used on private, trusted LANs that the end user is in physical and logical control of (or ought to be, at least). The host/IP is generally going to be configured either directly by the user or assigned automatically on the LAN and retrieved via Philips's cloud service, so it's hard to imagine MITM attacks being a likely risk. And the communication to the bridge is still encrypted even without verification, so there's still the protection against other devices sniffing keys and such. Right?

ticalc-travis avatar May 20 '22 18:05 ticalc-travis

Yes, I would have thought that disabling the certificate verification is probably the way to go -- or at least allowing people a choice between disabling it or putting a cert on their filesystem.

quentinsf avatar May 26 '22 10:05 quentinsf

Hi @quentinsf any thoughts on if we'll see this merge soon?

entrippy avatar Dec 16 '23 13:12 entrippy

Hi @quentinsf any thoughts on if we'll see this merge soon?

I think Travis still considers it a 'work in progress', and I'm afraid I don't have time to devote to it at present. But when he's happy with it...

Q

quentinsf avatar Dec 31 '23 12:12 quentinsf

Unfortunately, I too can no longer devote any time to testing/finishing this. But if anyone wants to take over the work, feel free. :-)

ticalc-travis avatar Jan 14 '24 18:01 ticalc-travis