8000 Added working support for private storage by nickovs · Pull Request #16903 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Added working support for private storage #16903

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

Merged
merged 11 commits into from
Oct 2, 2018

Conversation

nickovs
Copy link
Contributor
@nickovs nickovs commented Sep 26, 2018

Description:

This is a fixed version of #16878. It adds support for marking Store objects objects as private to prevent data exposure.

Compared to the original PR it:

  • fixes the corruption bug in the original PR caused by not properly truncating the storage file when writing JSON files using utils.json.save_json()
  • Implements atomic file replacement in the helpers.storage.Store class to prevent file corruption if the system crashes while writing a storage file.
  • Ensures that the file permissions of existing storage files get updated if they are now marked as private and the contents is updated.
  • Adds test cases to test/helpers/test_storage.py to test that updating an existing storage file works correctly.

Related issue (if applicable): fixes #16349

Pull request in home-assistant.io with documentation (if applicable): N/A

Example entry for configuration.yaml (if applicable):

N/A

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox.

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

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

  • New dependencies have been added to the REQUIREMENTS variable (example). N/A
  • New dependencies are only imported inside functions that use them (example). N/A
  • New or updated dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py. N/A
  • New files were added to .coveragerc. N/A

If the code does not interact with devices:

  • Tests have been added to verify that the new code works. N/A

@nickovs nickovs requested a review from a team as a code owner September 26, 2018 19:02
@homeassistant homeassistant added core small-pr PRs with less than 30 lines. cla-signed labels Sep 26, 2018
@ghost ghost added the in progress label Sep 26, 2018
@nickovs nickovs mentioned this pull request Sep 26, 2018
7 tasks
@amelchio
Copy link
Contributor

Sorry, I removed some of your changes in #16909 to get rid of CI failures.

Please add them back in this PR :)

@nickovs
Copy link
Contributor Author
nickovs commented Sep 26, 2018

@amelchio I fixed the merge conflict but it seems that you also reverted a fix to 8000 a broken test file (tests/components/emulated_hue/test_init.py) and I don't know how to put it back without pushing a whole new pull request. Any suggestions?

@nickovs
Copy link
Contributor Author
nickovs commented Sep 27, 2018

OK, I just added the file back at my end and pushed it again. It seems to work now.

@@ -187,7 +187,9 @@ def _write_data(self, path: str, data: Dict):
os.makedirs(os.path.dirname(path))

_LOGGER.debug('Writing data for %s', self.key)
json.save_json(path, data, self._private)
tmp_path = path + "__TEMP__"
Copy link
Member

Choose a reason for hiding this comment

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

Mark file as not visible with ., and we sh 8000 ould use a context manager to cleanup the temporary file after this.

Copy link
Member

Choose a reason for hiding this comment

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

No need to clean up since we're using os.replace

@amelchio
Copy link
Contributor

@nickovs Yes, fine to handle the revert like that 👍. You can push additional commits until the PR is merged, that will also work to address review comments.

@@ -30,6 +31,14 @@ def store(hass):
assert data == MOCK_DATA


async def test_overwriting(hass, store):
Copy link
Member

Choose a reason for hiding this comment

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

This actually doesn't do anything because all writes for the storage helper are mocked in tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aha. Does that mean that the current storage implementation does not get tested down the filesystem level with the existing unit tests? If that's the case, is it fine to leave this out altogether?

Copy link
Member

Choose a reason for hiding this comment

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

Correct, we try to avoid I/O as much as possible in unit tests as it's slow.

We should still test this functionality but it should test util.save_json directly, as that one is not mocked out.

with open(fname, "w") as fh:
fh.write(TEST_BAD_SERIALIED)
with self.assertRaises(HomeAssistantError):
data = load_json(fname)

Choose a reason for hiding this comment

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

local variable 'data' is assigned to but never used

save_json(fname, TEST_JSON_B)
data = load_json(fname)
self.assertEqual(data, TEST_JSON_B)

Choose a reason for hiding this comment

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

blank line contains whitespace

for fname in os.listdir(self.tmp_dir):
os.remove(os.path.join(self.tmp_dir, fname))
os.rmdir(self.tmp_dir)

Choose a reason for hiding this comment

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

blank line contains whitespace

# Test data that can not be loaded as JSON
TEST_BAD_SERIALIED = "THIS IS NOT JSON\n"

class TestJSON(unittest.TestCase):

Choose a reason for hiding this comment

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

expected 2 blank lines, found 1

TEST_JSON_A = {"a":1, "B":"two"}
TEST_JSON_B = {"a":"one", "B":2}
# Test data that can not be saved as JSON (keys must be strings)
TEST_BAD_OBJECT = {("A",):1}

Choose a reason for hiding this comment

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

missing whitespace after ':'


# Test data that can be saved as JSON
TEST_JSON_A = {"a":1, "B":"two"}
TEST_JSON_B = {"a":"one", "B":2}

Choose a reason for hiding this comment

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

missing whitespace after ':'

from homeassistant.exceptions import HomeAssistantError

# Test data that can be saved as JSON
TEST_JSON_A = {"a":1, "B":"two"}

Choose a reason for hiding this comment

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

missing whitespace after ':'

import sys
from tempfile import mkdtemp

from homeassistant.util.json import (SerializationError, WriteError,

Choose a reason for hiding this comment

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

'homeassistant.util.json.WriteError' imported but unused

TEST_JSON_A = {"a" : 1, "B" : "two"}
TEST_JSON_B = {"a" : "one", "B" : 2}
# Test data that can not be saved as JSON (keys must be strings)
TEST_BAD_OBJECT = {("A",) : 1}

Choose a reason for hiding this comment

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

whitespace before ':'


# Test data that can be saved as JSON
TEST_JSON_A = {"a" : 1, "B" : "two"}
TEST_JSON_B = {"a" : "one", "B" : 2}

Choose a reason for hiding this comment

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

whitespace before ':'

from homeassistant.exceptions import HomeAssistantError

# Test data that can be saved as JSON
TEST_JSON_A = {"a" : 1, "B" : "two"}

Choose a reason for hiding this comment

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

whitespace before ':'

@nickovs
Copy link
Contributor Author
nickovs commented Sep 28, 2018

OK. I wrote a test suite for the underlying util/json.py code, which was largely untested before. These tests of necessity do some I/O, since they are testing file system operations, but they take very little time to do so and it's good to have this code tested. There are still some pathways between the upper layers of the storage system and the low-level file representation but, as discussed above in the code comments, this would require some rather different test suites to be written.

json.save_json(path, data, self._private)
tmp_path = path + "__TEMP__"
json.save_json(tmp_path, data, self._private)
os.replace(tmp_path, path)
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 that we should move this functionality to save_json so that all calls can benefit.

I also think that we should consider cleaning up the temp path in case of an exception replacing the other file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair points. I'll make it so.

Added extra clean-up code to ensure that temporary files are removed in
case of errors.
Updated emulated_hue unit tests to avoid errors.
@balloob balloob merged commit b0b3620 into home-assistant:dev Oct 2, 2018
@ghost ghost removed the in progress label Oct 2, 2018
@balloob
Copy link
Member
balloob commented Oct 2, 2018

Alright let's try again, great work! 👍

@balloob balloob mentioned this pull request Oct 12, 2018
nickovs added a commit to nickovs/home-assistant that referenced this pull request Oct 20, 2018
…ous writes

Reworked tests/components/emulated_hue/test_init.py to not be
dependent on the specific internal implementation of util/jsonn.py
balloob pushed a commit that referenced this pull request Oct 23, 2018
…7636)

Reworked tests/components/emulated_hue/test_init.py to not be
dependent on the specific internal implementation of util/jsonn.py
balloob pushed a commit that referenced this pull request Oct 23, 2018
…7636)

Reworked tests/components/emulated_hue/test_init.py to not be
dependent on the specific internal implementation of util/jsonn.py
@balloob balloob mentioned this pull request Oct 26, 2018
@home-assistant home-assistant locked and limited conversation to collaborators Feb 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Authentication data has wrong permissions
6 participants
0