Skip to content

Commit 8d796d6

Browse files
committed
Partial compatibility with Google security update 2021
Google Drive added a new "resourceKey" attribute required to access documents shared by links. This resourceKey must be passed through HTTP header, aside with the document ID. resourceKey can be retrieved from a previous list operation on containing folder. Partial implementation; only for basic methods: GetContentFile, GetContentIOBuffer and FetchMetadata.
1 parent cb7814b commit 8d796d6

2 files changed

Lines changed: 106 additions & 9 deletions

File tree

pydrive2/files.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -453,16 +453,14 @@ def FetchMetadata(self, fields=None, fetch_all=False):
453453

454454
if file_id:
455455
try:
456-
metadata = (
457-
self.auth.service.files()
458-
.get(
459-
fileId=file_id,
460-
fields=fields,
461-
# Teamdrive support
462-
supportsAllDrives=True,
463-
)
464-
.execute(http=self.http)
456+
request = self.auth.service.files().get(
457+
fileId=file_id,
458+
fields=fields,
459+
# Teamdrive support
460+
supportsAllDrives=True,
465461
)
462+
request = self._AddResourceKeyHeaders(request)
463+
metadata = request.execute(http=self.http)
466464
except errors.HttpError as error:
467465
raise ApiRequestError(error)
468466
else:
@@ -687,6 +685,24 @@ def _WrapRequest(self, request):
687685
"""
688686
if self.http:
689687
request.http = self.http
688+
request = self._AddResourceKeyHeaders(request)
689+
return request
690+
691+
def _AddResourceKeyHeaders(self, request):
692+
"""Add resourceKey headers to request if file is secured with resourceKey and
693+
its available (from a list for example).
694+
695+
:param request: request to add headers to.
696+
:type request: googleapiclient.http.HttpRequest
697+
"""
698+
file_id = self.metadata.get("id") or self.get("id")
699+
resourceKey = self.metadata.get("resourceKey") or self.get(
700+
"resourceKey"
701+
)
702+
if file_id and resourceKey:
703+
request.headers["X-Goog-Drive-Resource-Keys"] = (
704+
f"{file_id}/{resourceKey}"
705+
)
690706
return request
691707

692708
@LoadAuth

pydrive2/test/test_file.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,87 @@ def test_Files_Get_Content_Buffer(self):
356356

357357
self.DeleteUploadedFiles(drive, [file1["id"]])
358358

359+
def test_Files_Get_Content_Buffer_resourceKey_missing(self):
360+
"""404 expected for file secured with resourceKey when not provided."""
361+
drive = GoogleDrive(self.ga)
362+
file1 = drive.CreateFile(
363+
{
364+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
365+
}
366+
)
367+
with self.assertRaisesRegex(
368+
ApiRequestError, "HttpError 404 when requesting"
369+
):
370+
pydrive_retry(file1.GetContentIOBuffer)
371+
372+
def test_Files_Get_Content_Buffer_resourceKey(self):
373+
drive = GoogleDrive(self.ga)
374+
file1 = drive.CreateFile(
375+
{
376+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
377+
"resourceKey": "0-vjzOveuin3fnf4LUlfsD3A",
378+
}
379+
)
380+
381+
buffer1 = pydrive_retry(file1.GetContentIOBuffer)
382+
383+
self.assertEqual(len(buffer1), 6128902)
384+
385+
def test_Files_Get_Content_File_resourceKey_missing(self):
386+
"""404 expected for file secured with resourceKey when not provided."""
387+
drive = GoogleDrive(self.ga)
388+
file1 = drive.CreateFile(
389+
{
390+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
391+
}
392+
)
393+
fileOut = self.getTempFile()
394+
with self.assertRaisesRegex(
395+
ApiRequestError, "HttpError 404 when requesting"
396+
):
397+
pydrive_retry(file1.GetContentFile, fileOut)
398+
399+
def test_Files_Get_Content_File_resourceKey(self):
400+
drive = GoogleDrive(self.ga)
401+
file1 = drive.CreateFile(
402+
{
403+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
404+
"resourceKey": "0-vjzOveuin3fnf4LUlfsD3A",
405+
}
406+
)
407+
408+
fileOut = self.getTempFile()
409+
pydrive_retry(file1.GetContentFile, fileOut)
410+
411+
with open(fileOut, "rb") as f:
412+
self.assertEqual(len(f.read()), 6128902)
413+
414+
def test_Files_Fetch_Metadata_resourceKey_missing(self):
415+
"""404 expected for file secured with resourceKey when not provided."""
416+
drive = GoogleDrive(self.ga)
417+
file1 = drive.CreateFile(
418+
{
419+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
420+
}
421+
)
422+
with self.assertRaisesRegex(
423+
ApiRequestError, "HttpError 404 when requesting"
424+
):
425+
pydrive_retry(file1.FetchMetadata)
426+
427+
def test_Files_Fetch_Metadata_Buffer_resourceKey(self):
428+
drive = GoogleDrive(self.ga)
429+
file1 = drive.CreateFile(
430+
{
431+
"id": "0BxphPoRgwhnodHNjS3JESnFNS1E",
432+
"resourceKey": "0-vjzOveuin3fnf4LUlfsD3A",
433+
}
434+
)
435+
436+
pydrive_retry(file1.FetchMetadata)
437+
438+
self.assertEqual(file1.metadata["title"], "N48E012.zip")
439+
359440
def test_Upload_Download_Empty_File(self):
360441
filename = os.path.join(self.tmpdir, str(time()))
361442
create_file(filename, "")

0 commit comments

Comments
 (0)