Open jslay88 opened 1 year ago
Thanks! Will look into Fernet. I've been wanting to move away from pickle for a long while but haven't had a chance yet. Most of the pickled data is already using pydantic, so I think we could easily dump/load json.
Ahh yeah, didn't think about that. Pydantic has a JSON serialization method built in to the models.
Any thoughts on requests-cache? It seems to offer a Fernet serialization option.
Could potentially offer a good balance of caching the necessary api responses while also being able to refresh the data every now and then.
Sorry for the delayed response. Busy week.
I have never actually used their serialization before. I have always just used it as a lightweight caching layer on requests, and never serialized to disk from it. However, I assume they are using very similar approaches, by just taking the byte stream from the response and encrypting it directly. But I assume you could have it handle whatever you want (say JSON), since it looks like you are going to have to implement your own SerializerPipeline to make it use Fernet for the dumps and loads stage of the SerializerPipeline regardless.
Also, was thinking about your implementation with Pydantic, wonder if it might be worth moving from Flask to FastAPI for the backend as well, giving you the ability to do async properly. FastAPI has direct support for Pydantic models as well (Flask may have this now, its been a minute since I've explored with it). But this would require you to either separate the frontend with node or similar, or integrate Jinja into FastAPI. Just ideas for you to play with.
I am just glad I didn't have to reverse engineer all this Wyze stuff with a proxy myself.
Just to add a little more security, since Wyze accounts can have things tied to them such as front door locks, it would be nice to be able to supply an encryption key for the application to use (either via UTF-8 binary file/single-line text file (same thing), or envvar) to encrypt and decrypt the pickle file. This way, the pickle file will be encrypted at rest.
I'd recommend going the easy route and just using Fernet.
Then adding something to the GUI where you can encrpyt, and it returns the key for safe storage. Further implementation best as you see fit.
You may also want to abandon pickle at some point, as there are inherit security risks to using it, as well as other issues when upgrading supporting Python modules and Python version. Usually, pickle is reserved for when you have no better serialization method (such as JSON or others). See also.
From a quick look at your code (will admit, looked for about 5 minutes), it looks like you may be able to use a dataclass to store all of your state, then you could easily serialize to JSON with
json.dumps(my_state.__dict__)
, encode it and feed it to Fernet encrypt. You could also then unserialize using dict spreader/expander or thedacite
module for nested structures.Thankfully, this Fernet implementation is agnostic to whatever serialization method you use, as you just feed it bytes to encrypt and decrypt (whether that's JSON, pickle, etc.).