Skip to content

Commit a1a8793

Browse files
authored
Support JSON based service auth (#81)
* Support authentication from json service account file * Add tests * mark p12 tests with skip
1 parent 1a51f6c commit a1a8793

File tree

5 files changed

+70
-19
lines changed

5 files changed

+70
-19
lines changed

pydrive2/auth.py

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,7 @@ class GoogleAuth(ApiAttributeMixin, object):
161161
"revoke_uri",
162162
"redirect_uri",
163163
]
164-
SERVICE_CONFIGS_LIST = [
165-
"client_service_email",
166-
"client_user_email",
167-
"client_pkcs12_file_path",
168-
]
164+
SERVICE_CONFIGS_LIST = ["client_user_email"]
169165
settings = ApiAttribute("settings")
170166
client_config = ApiAttribute("client_config")
171167
flow = ApiAttribute("flow")
@@ -296,14 +292,21 @@ def ServiceAuth(self):
296292
if set(self.SERVICE_CONFIGS_LIST) - set(self.client_config):
297293
self.LoadServiceConfigSettings()
298294
scopes = scopes_to_string(self.settings["oauth_scope"])
295+
client_service_json = self.client_config.get("client_json_file_path")
296+
if client_service_json:
297+
self.credentials = ServiceAccountCredentials.from_json_keyfile_name(
298+
filename=client_service_json, scopes=scopes
299+
)
300+
else:
301+
service_email = self.client_config["client_service_email"]
302+
file_path = self.client_config["client_pkcs12_file_path"]
303+
self.credentials = ServiceAccountCredentials.from_p12_keyfile(
304+
service_account_email=service_email,
305+
filename=file_path,
306+
scopes=scopes,
307+
)
308+
299309
user_email = self.client_config.get("client_user_email")
300-
service_email = self.client_config["client_service_email"]
301-
file_path = self.client_config["client_pkcs12_file_path"]
302-
self.credentials = ServiceAccountCredentials.from_p12_keyfile(
303-
service_account_email=service_email,
304-
filename=file_path,
305-
scopes=scopes,
306-
)
307310
if user_email:
308311
self.credentials = self.credentials.create_delegated(
309312
sub=user_email
@@ -322,6 +325,8 @@ def LoadCredentials(self, backend=None):
322325
raise InvalidConfigError("Please specify credential backend")
323326
if backend == "file":
324327
self.LoadCredentialsFile()
328+
elif backend == "json":
329+
self.LoadCredentialsFileJson()
325330
else:
326331
raise InvalidConfigError("Unknown save_credentials_backend")
327332

@@ -348,6 +353,19 @@ def LoadCredentialsFile(self, credentials_file=None):
348353
"Credentials file cannot be symbolic link"
349354
)
350355

356+
def LoadCredentialsFileJson(self, credentials_file=None):
357+
if credentials_file is None:
358+
credentials_file = self.settings.get("save_credentials_file")
359+
if credentials_file is None:
360+
raise InvalidConfigError(
361+
"Please specify credentials file to read"
362+
)
363+
364+
scopes = scopes_to_string(self.settings["oauth_scope"])
365+
self.credentials = ServiceAccountCredentials.from_json_keyfile_name(
366+
filename=credentials_file, scopes=scopes
367+
)
368+
351369
def SaveCredentials(self, backend=None):
352370
"""Saves credentials according to specified backend.
353371
@@ -471,6 +489,21 @@ def LoadServiceConfigSettings(self):
471489
"""Loads client configuration from settings file.
472490
:raises: InvalidConfigError
473491
"""
492+
for file_format in ["json", "pkcs12"]:
493+
config = f"client_{file_format}_file_path"
494+
value = self.settings["service_config"].get(config)
495+
if value:
496+
self.client_config[config] = value
497+
break
498+
else:
499+
raise InvalidConfigError(
500+
"Either json or pkcs12 file path required "
501+
"for service authentication"
502+
)
503+
504+
if file_format == "pkcs12":
505+
self.SERVICE_CONFIGS_LIST.append("client_service_email")
506+
474507
for config in self.SERVICE_CONFIGS_LIST:
475508
try:
476509
self.client_config[config] = self.settings["service_config"][
@@ -516,7 +549,7 @@ def GetFlow(self):
516549
self.client_config["client_id"],
517550
self.client_config["client_secret"],
518551
scopes_to_string(self.settings["oauth_scope"]),
519-
**constructor_kwargs
552+
**constructor_kwargs,
520553
)
521554
if self.settings.get("get_refresh_token"):
522555
self.flow.params.update(

pydrive2/settings.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@
7272
"required": True,
7373
"default": None,
7474
},
75-
"client_service_email": {"type": str, "required": True},
76-
"client_pkcs12_file_path": {"type": str, "required": True},
75+
"client_service_email": {"type": str, "required": False},
76+
"client_pkcs12_file_path": {"type": str, "required": False},
77+
"client_json_file_path": {"type": str, "required": False},
7778
},
7879
},
7980
"oauth_scope": {

pydrive2/test/settings/default.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
client_config_backend: service
22
service_config:
3-
client_service_email: your-service-account-email
4-
client_pkcs12_file_path: your-file-path.p12
3+
client_json_file_path: your-file-path.json
54

65
save_credentials: True
7-
save_credentials_backend: file
6+
save_credentials_backend: json
87
save_credentials_file: credentials/default.dat
98

109
oauth_scope:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
client_config_backend: service
2+
service_config:
3+
client_json_file_path: your-file-path.json
4+
5+
save_credentials: True
6+
save_credentials_backend: json
7+
save_credentials_file: credentials/7.dat
8+
9+
oauth_scope:
10+
- https://www.googleapis.com/auth/drive

pydrive2/test/test_oauth.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,21 @@ def test_05_ConfigFromSettingsWithoutOauthScope(self):
7373
self.assertEqual(ga.access_token_expired, False)
7474
time.sleep(1)
7575

76-
def test_06_ServiceAuthFromSavedCredentialsFile(self):
76+
@pytest.mark.skip(reason="P12 authentication is deprecated")
77+
def test_06_ServiceAuthFromSavedCredentialsP12File(self):
7778
setup_credentials("credentials/6.dat")
7879
ga = GoogleAuth(settings_file_path("test_oauth_test_06.yaml"))
7980
ga.ServiceAuth()
8081
self.assertEqual(ga.access_token_expired, False)
8182
time.sleep(1)
8283

84+
def test_07_ServiceAuthFromSavedCredentialsJsonFile(self):
85+
setup_credentials("credentials/7.dat")
86+
ga = GoogleAuth(settings_file_path("test_oauth_test_07.yaml"))
87+
ga.ServiceAuth()
88+
self.assertEqual(ga.access_token_expired, False)
89+
time.sleep(1)
90+
8391
def CheckCredentialsFile(self, credentials, no_file=False):
8492
ga = GoogleAuth(settings_file_path("test_oauth_default.yaml"))
8593
ga.LoadCredentialsFile(credentials)

0 commit comments

Comments
 (0)