Making save_to_well_known_file() save with 0600 permission.

Fixes #144.

H/T to http://stackoverflow.com/a/5624691/1068170 and
       http://stackoverflow.com/a/5337329/1068170
This commit is contained in:
Danny Hermes
2015-03-25 13:31:15 -07:00
parent f79c2cd301
commit 21c2458479
2 changed files with 48 additions and 3 deletions

View File

@@ -28,7 +28,9 @@ import logging
import os
import socket
import sys
import tempfile
import time
import shutil
import six
from six.moves import urllib
@@ -1208,6 +1210,21 @@ class GoogleCredentials(OAuth2Credentials):
'method should point to a file.')
def _save_private_file(filename, json_contents):
"""Saves a file with read-write permissions on for the owner.
Args:
filename: String. Absolute path to file.
json_contents: JSON serializable object to be saved.
"""
temp_filename = tempfile.mktemp()
file_desc = os.open(temp_filename, os.O_WRONLY | os.O_CREAT, 0o600)
with os.fdopen(file_desc, 'w') as file_handle:
json.dump(json_contents, file_handle, sort_keys=True,
indent=2, separators=(',', ': '))
shutil.move(temp_filename, filename)
def save_to_well_known_file(credentials, well_known_file=None):
"""Save the provided GoogleCredentials to the well known file.
@@ -1226,9 +1243,7 @@ def save_to_well_known_file(credentials, well_known_file=None):
well_known_file = _get_well_known_file()
credentials_data = credentials.serialization_data
with open(well_known_file, 'w') as f:
json.dump(credentials_data, f, sort_keys=True, indent=2, separators=(',', ': '))
_save_private_file(well_known_file, credentials_data)
def _get_environment_variable_file():

View File

@@ -1112,5 +1112,35 @@ class MemoryCacheTests(unittest.TestCase):
self.assertEqual(None, m.get('foo'))
class Test__save_private_file(unittest.TestCase):
def _save_helper(self, filename):
contents = []
contents_str = '[]'
client._save_private_file(filename, contents)
with open(filename, 'r') as f:
stored_contents = f.read()
self.assertEqual(stored_contents, contents_str)
stat_mode = os.stat(filename).st_mode
# Octal 777, only last 3 positions matter for permissions mask.
stat_mode &= 0o777
self.assertEqual(stat_mode, 0o600)
def test_new(self):
import tempfile
filename = tempfile.mktemp()
self.assertFalse(os.path.exists(filename))
self._save_helper(filename)
def test_existing(self):
import tempfile
filename = tempfile.mktemp()
with open(filename, 'w') as f:
f.write('a bunch of nonsense longer than []')
self.assertTrue(os.path.exists(filename))
self._save_helper(filename)
if __name__ == '__main__':
unittest.main()